package com.zds.hj.poseidon.biz.dispatcher.credit.demo4;

import com.zds.boot.common.exception.BusinessException;
import com.zds.boot.dispatch.annotation.DispatcherHandler;
import com.zds.boot.dispatch.comm.enums.InstructTypeEnum;
import com.zds.boot.dispatch.comm.enums.ModuleNodeTypeEnum;
import com.zds.boot.dispatch.dto.BaseReqModel;
import com.zds.boot.dispatch.dto.BaseResultModel;
import com.zds.boot.dispatch.dto.InstructDto;
import com.zds.boot.dispatch.dto.InstructRegisterModule;
import com.zds.hj.icmc.facade.auth.assetcenter.dto.req.LiveVerifyReqDto;
import com.zds.hj.icmc.facade.auth.assetcenter.dto.resp.AuthRespDto;
import com.zds.hj.icmc.facade.auth.assetcenter.dto.resp.LiveVerifyRespDto;
import com.zds.hj.icmc.facade.auth.assetcenter.enums.LiveVerifyOperEnum;
import com.zds.hj.poseidon.biz.cba.hpp.domain.credit.service.layout.CreditApplyService;
import com.zds.hj.poseidon.biz.common.IcmcServiceInterface;
import com.zds.hj.poseidon.biz.dispatcher.credit.CreditCheckAbsHandler;
import com.zds.hj.poseidon.facade.dto.hpp.credit.CreditInfoEntityDto;
import com.zds.hj.product.facade.constant.ApplicationContainerConstant;
import com.zds.zly.common.enums.HjResultCodeEnum;
import com.zds.zly.common.utils.EmptyChecker;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@DispatcherHandler(value = "AuthLiveHandler", desc = "人脸识别模块", applicationContainer = ApplicationContainerConstant.FRONT_END, nodeType = ModuleNodeTypeEnum.BUSINESS)
@Slf4j
public class AuthLiveHandler extends CreditCheckAbsHandler {
    @Resource
    private CreditApplyService creditApplyService;
    @Resource
    private IcmcServiceInterface icmcServiceInterface;
    /**
     * 活体回调地址
     */
    private static final String RESULT_URL = "RESULT_URL";
    /**
     * 活体有效期
     */
    private static final String LIVE_EXPIRY_DATE = "LIVE_EXPIRY_DATE";
    /**
     * 活体验证结果
     */
    private static final String TRUE = "SUCCESSFUL_AUTH";

    @Override
    public void creditDoExecute(BaseReqModel params, BaseResultModel resultModel, CreditInfoEntityDto reqData, CreditInfoEntityDto dbData) {
        log.info("人脸识别开始执行===============================");
        CreditInfoEntityDto creditOnTransit = creditApplyService.findCreditOnTransit(params);
        //获取人脸识别结果
        LiveVerifyReqDto reqDto = new LiveVerifyReqDto();
        reqDto.setOperEnum(LiveVerifyOperEnum.CHECK);
        reqDto.setSerialNo(reqData.getSerialNo());
        reqDto.setUserId(String.valueOf(creditOnTransit.getId()));
        reqDto.setChannelNo(creditOnTransit.getCardId());
        AuthRespDto<LiveVerifyRespDto> respDto = icmcServiceInterface.liveVerify(reqDto);

        if (EmptyChecker.isEmpty(respDto.getAuditStatusEnum())){
            throw new BusinessException("人脸识别失败", HjResultCodeEnum.PARAMS_VALIDATE_FAIL.code());
        }
        if (!creditOnTransit.getName().equals(respDto.getData().getName()) || !creditOnTransit.getCardId().equals(respDto.getData().getIdNo())){
            throw new BusinessException("信息不匹配", HjResultCodeEnum.PARAMS_VALIDATE_FAIL.code());
        }
        //保存人脸识别回调地址
        dbData.setFaceUrl(reqData.getFaceUrl());
        //保存人脸识别结果
        dbData.setIsTrue(TRUE);
    }

    @Override
    public Object echoDetail(BaseReqModel params) {
        log.info("人脸识别回显开始===============================");
        CreditInfoEntityDto creditOnTransit = creditApplyService.findCreditOnTransit(params);
        //获取人脸识别
        LiveVerifyReqDto reqDto = new LiveVerifyReqDto();
        reqDto.setOperEnum(LiveVerifyOperEnum.URL);
        reqDto.setThirdSerialNo(String.valueOf(params.getBizNo()));
        reqDto.setName(creditOnTransit.getName());
        reqDto.setIdNo(creditOnTransit.getCardId());
        reqDto.setUserId(String.valueOf(creditOnTransit.getId()));
        //模块配置 获取回调地址
        List<InstructDto> instructSettingDtoList = params.getDispatchModuleNodes().getInstructSettingDtos();
        Map<String, String> key = instructSettingDtoList.stream().collect(Collectors.toMap(InstructDto::getInstructCode, InstructDto::getValues));
        String url = key.get(RESULT_URL);
        reqDto.setResultsShowUrl(url);
        reqDto.setChannelNo(String.valueOf(params.getBizNo()));
        AuthRespDto<LiveVerifyRespDto> respDto = icmcServiceInterface.liveVerify(reqDto);
        //返回人脸识别回调地址和流水号
        Map<String,Object> map = new HashMap<>(2);
        map.put("faceUrl",respDto.getData().getResultsShowUrl());
        map.put("serialNo",respDto.getData().getSerialNo());
        return map;
    }

    @Override
    public Boolean skipThisStep(BaseReqModel params){
        log.info("人脸识别跳过开始============================");
        CreditInfoEntityDto creditOnTransit = creditApplyService.findCreditOnTransit(params);
        //模块配置 获取活体有效期
        List<InstructDto> instructSettingDtoList = params.getDispatchModuleNodes().getInstructSettingDtos();
        Map<String, String> key = instructSettingDtoList.stream().collect(Collectors.toMap(InstructDto::getInstructCode, InstructDto::getValues));
        int day = Integer.parseInt(key.get(LIVE_EXPIRY_DATE));

        long date = (long) day * 24 * 60 * 60 * 1000 ;
        long current_time = System.currentTimeMillis();
        long date1 = creditOnTransit.getApplyDate().getTime();
        //验证识别结果是否正确且在有效期内
        if (TRUE.equals(creditOnTransit.getIsTrue())){
            if (current_time - date <= date1){
                log.info("活体认证有效期内，跳过本次认证，bizNo:{}",params.getBizNo());
                return true;
            }
        }
        return false;
    }

    @Override
    public Object paramsFerry(Object o) {
        CreditInfoEntityDto dbDto = (CreditInfoEntityDto) o;
        CreditInfoEntityDto creditInfoEntityDto = new CreditInfoEntityDto();
        creditInfoEntityDto.setFaceUrl(dbDto.getFaceUrl());
        creditInfoEntityDto.setIsTrue(dbDto.getIsTrue());
        creditInfoEntityDto.setName(dbDto.getName());
        creditInfoEntityDto.setCardNo(dbDto.getCardNo());
        creditInfoEntityDto.setSerialNo(dbDto.getSerialNo());
        return creditInfoEntityDto;
    }

    /**
     * @Author jingyh
     * @Description 指令集
     * @param
     * @return java.util.List<com.zds.boot.dispatch.dto.InstructRegisterModule>
     **/
    @Override
    public List<InstructRegisterModule> moduleInstructs() {

        List<InstructRegisterModule> instructRegisterModules = new ArrayList<>();

        InstructRegisterModule registerModule0 = new InstructRegisterModule();
        registerModule0.setInstructCode(RESULT_URL);
        registerModule0.setInstructName("活体回调地址");
        registerModule0.setInstructTitle("活体回调地址");
        registerModule0.setInstructType(InstructTypeEnum.ONE_LINE_TEXT);
        registerModule0.setInstructEmphatic("活体回调地址");
        registerModule0.setEmptyCheck(true);
        instructRegisterModules.add(registerModule0);

        InstructRegisterModule registerModule1 = new InstructRegisterModule();
        registerModule1.setInstructCode(LIVE_EXPIRY_DATE);
        registerModule1.setInstructName("活体有效期");
        registerModule1.setInstructTitle("活体有效期");
        registerModule1.setInstructType(InstructTypeEnum.NUMBER);
        registerModule1.setInstructEmphatic("活体有效期");
        registerModule1.setEmptyCheck(true);
        instructRegisterModules.add(registerModule1);

        return instructRegisterModules;
    }
}
